package com.runchinaup.runchilibrary.upg;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

import com.runchinaup.runchilibrary.modes.net.OKHttpUtil;
import com.runchinaup.runchilibrary.upg.core.BaseParser;
import com.runchinaup.runchilibrary.upg.core.NetCallback;
import com.runchinaup.runchilibrary.upg.core.ProgressResponse;
import com.squareup.okhttp.Call;
import com.squareup.okhttp.Interceptor;
import com.squareup.okhttp.Callback;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.Response;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;
import java.util.concurrent.TimeUnit;

/**
 * Created by nopointer on 2017/11/13.
 */

public class UpgHelper<N> {

    private static OKHttpUtil okHttpUtil = OKHttpUtil.getInstance();

    private static UpgHelper helper = null;
    private Context context;

    private UpgHelper(Context context) {
        this.context = context;
    }

    public static UpgHelper getInstance(Context context) {
        if (helper == null) {
            helper = new UpgHelper<>(context);
        }
        return helper;
    }

    public void getLastAppInfo(String url, BaseParser parser, NetCallback callback) {
        okHttpUtil.asyncGetRequest(url, resolveJson(parser, callback));
    }

    public static OkHttpClient download(OkHttpClient client, final ProgressResponse.ProgressResponseListener listener) {
        //克隆
        OkHttpClient clone = client.clone();
        //增加拦截器
        clone.networkInterceptors().add(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                //拦截
                Response originalResponse = chain.proceed(chain.request());
                return originalResponse.newBuilder().body(
                        new ProgressResponse(originalResponse.body(), listener))
                        .build();
            }
        });
        return clone;
    }

    private DownloadCallback callback = null;
    Call call = null;

    public void downLoad(final N bean, final Messager<N> messager, final DownloadCallback callback) {
        this.callback = callback;
        String appName = messager.returnName(bean);
        if (TextUtils.isEmpty(appName)) {
            appName = messager.returnPaakageName(bean);
            if (TextUtils.isEmpty(appName)) {
                appName = "tmp.demo";
            }
        }
        final File newAppFile = new File(context.getExternalCacheDir(), appName + ".apk");
        final Request request = new Request.Builder().url(messager.returnDownloadUrl(bean)).build();
        OkHttpClient client = new OkHttpClient();
        client.setConnectTimeout(1000, TimeUnit.MINUTES);
        client.setReadTimeout(1000, TimeUnit.MINUTES);
        client.setWriteTimeout(1000, TimeUnit.MINUTES);
        callback.onPrgress(0f);
        call = download(client, new ProgressResponse.ProgressResponseListener() {
            @Override
            public void onResponseProgress(long byteRead, long contentLen, boolean done) {
                callback.onPrgress(((byteRead * 1.f) / (messager.returnFileSize(bean))) * 100f);
            }
        }).newCall(request);
        if (call != null) {
            call.enqueue(new Callback() {

                @Override
                public void onFailure(Request request, IOException e) {
                    callback.onFailure();
                }

                @Override
                public void onResponse(Response response) throws IOException {
                    FileOutputStream outputStream = new FileOutputStream(newAppFile);
                    byte[] data = new byte[1024 * 4];
                    int len = 0;
                    InputStream in = response.body().byteStream();
                    try {
                        while ((len = in.read(data)) != -1) {
                            outputStream.write(data, 0, len);
                            outputStream.flush();
                        }
                        outputStream.close();
                        callback.onFinish(newAppFile);
                    } catch (SocketException exception) {
                        Log.e("debug_close", "关闭更新");
                    }
                }
            });
        }
    }

    public void cancel() {
        if (call != null)
            call.cancel();
        callback.onCancel();
    }


    public void toInstall(File newAppFile) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setDataAndType(Uri.fromFile(newAppFile),
                "application/vnd.android.package-archive");
        context.startActivity(intent);
    }


    public static abstract class DownloadCallback {
        public void onFailure() {
        }

        public void onCancel() {
        }

        public abstract void onPrgress(float pro);

        public abstract void onFinish(File newAppFile);
    }


    private static Callback resolveJson(final BaseParser parser, final NetCallback callback) {

        return new Callback() {
            @Override
            public void onFailure(Request request, IOException e) {
                if (e == null) return;
                e.printStackTrace();
                if (callback != null && !TextUtils.isEmpty(e.getMessage()))
                    callback.onFailure(e);
            }

            @Override
            public void onResponse(Response response) throws IOException {
                String body = response.body().string();
                if (callback != null)
                    callback.onResponse(parser.parserFromNet(body), body);
            }
        };
    }

}
